import crypto from "crypto";

// Encode an object as a cookie using a key using AES-GCM. (key must be 32 bytes or more)
const encodeCookie = (o: any, key: any) => {
  try {
    o.time = Math.floor(Date.now() / 1000); // Add the cookie creation time
    const iv = Buffer.from(crypto.randomBytes(12) as any, "binary"),
      cipher = crypto.createCipheriv("aes-256-gcm", key.slice(0, 32), iv);
    const crypted = Buffer.concat([
      cipher.update(JSON.stringify(o), "utf8"),
      cipher.final()
    ]);
    var r = Buffer.concat([iv, cipher.getAuthTag(), crypted])
      .toString("base64")
      .replace(/\+/g, "@")
      .replace(/\//g, "$");
    return r;
  } catch (ex) {
    console.log("ERR: Failed to encode AESGCM cookie due to exception: " + ex);
    return null;
  }
};

const generateMeshLoginToken = (meshUserID: any, meshLoginTokenKey: any) => {
  try {
    var loginCookieEncryptionKey = Buffer.from(meshLoginTokenKey, "hex");
  } catch (ex) {
    console.log(ex);
    return null;
  }
  if (
    loginCookieEncryptionKey == null ||
    loginCookieEncryptionKey.length < 32
  ) {
    console.log("Invalid key, must be at least 32 bytes long.");
    return null;
  } else {
    return encodeCookie({ u: meshUserID, a: 3 }, loginCookieEncryptionKey);
  }
};

export default generateMeshLoginToken;
